package com.core.ui.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.core.managers.LoginManager;
import com.core.managers.SessionManager;
import com.core.protocols.IAuthenticationDelegate;
import com.core.protocols.ICustomDatasourceDelegate;
import com.core.protocols.IMenuDatasource;
import com.core.protocols.IServiceLayerDelegate;
import com.core.servicelayer.MenuServiceLayer;
import com.core.ui.controller.base.CustomController;
import com.core.ui.customview.MenuItemCell;
import com.core.utils.HibernateParameter;
import com.model.MenuItem;
import com.model.UserContextName;

public class MenuController
        extends CustomController
        implements IMenuDatasource, IServiceLayerDelegate {

	private MenuServiceLayer        menuServiceLayer = null;
	ArrayList <MenuItemCell>        menuItemCellList = null;

	private IAuthenticationDelegate authenticationDelegate;



	public IAuthenticationDelegate getAuthenticationDelegate () {

		return authenticationDelegate;
	}

	private ICustomDatasourceDelegate delegate = null;



	public void setAuthenticationDelegate ( IAuthenticationDelegate authenticationDelegate ) {

		this.authenticationDelegate = authenticationDelegate;
	}



	public MenuController() {

		authenticationDelegate = null;
	}



	public void finalize ()
	        throws Throwable {

		try {
			authenticationDelegate = null;
			menuItemCellList = null;
		} finally {
			super.finalize();
		}
	}



	/**
	 * 
	 * ICustomDatasource
	 */

	@Override
	public void setCustomDatasourceDelegate ( ICustomDatasourceDelegate delegate ) {

		this.delegate = delegate;

	}



	@Override
	public void reloadData () {



		String script = "";
		script += " join MenuItem.userContextNameToExecute as UCN,";
		script += " com.model.user.User as User";
		script += " join User.userCategory.userRole.availableContexts as availableUCN";
		script += " where UCN IN (availableUCN)";
		script += " and User.id=:ID";

		Set <HibernateParameter> params = new HashSet <HibernateParameter>();
		params.add(new HibernateParameter("ID", LoginManager.sharedInstance().getUserId()));

		menuServiceLayer = new MenuServiceLayer();
		menuServiceLayer.setLayerDelegate(this);
		menuServiceLayer.performRequestWithFilter(script, params);
	}



	/**
	 * 
	 * 
	 * IServiceLayerDelegate
	 */


	@Override
	public <T> void responseResponseItemsList ( final List <T> items,
	                                            final Object request,
	                                            final Exception exception ) {

		if ( exception != null ) {
			return;
		}
		if ( items == null ) {
			return;
		}
		if ( delegate == null ) {
			return;
		}


		menuItemCellList = new ArrayList <MenuItemCell>();
		for ( T item : items ) {

			MenuItem pojo = (MenuItem) item;

			Boolean canBeSelected = this.canItemBeSelected(pojo);

			String linkURL = pojo.getServletNameToExecute();

			MenuItemCell result = new MenuItemCell();
			result.setSelected(canBeSelected);
			result.setName(pojo.getName());
			result.setLinkURL(linkURL);
			result.setStyleClassName("header_menu_item");
			result.setLinkStyleClassName("header_menu_link");
			result.setSelectedStyleClassName("header_menu_item_selected");

			menuItemCellList.add(result);

		}

		delegate.refreshContent();

	}



	/**
	 * 
	 * IMenuDatasource
	 */

	@Override
	public int numberOfItems () {

		int result = 0;
		if ( menuItemCellList != null ) {
			result = menuItemCellList.size();
		}
		return result;
	}



	@Override
	public MenuItemCell itemAtIndex ( int index ) {

		MenuItemCell result = null;
		if ( menuItemCellList != null ) {
			result = menuItemCellList.get(index);
		}
		return result;
	}



	/**
	 * 
	 * @param item
	 * @return
	 */


	private Boolean canItemBeSelected ( MenuItem item ) {

		if ( item == null ) {
			return false;
		}

		SessionManager sessionManager = SessionManager.sharedInstance();
		String sessionManagerContextName = (String) sessionManager.getUserContextName();
		if ( sessionManagerContextName == null ) {
			return false;
		}

		Set <UserContextName> userContextNames = item.getUserContextNameVisibleIn();
		if ( userContextNames == null ) {
			return false;
		}

		if ( userContextNames.size() == 0 ) {
			return false;
		}

		String[] pageContextNames = sessionManagerContextName.split(";");
		if ( pageContextNames.length == 0 ) {
			return false;
		}

		boolean isSelected = false;
		Iterator <UserContextName> iterator = userContextNames.iterator();
		while ( iterator.hasNext() ) {
			UserContextName userContextName = iterator.next();
			for ( int j = 0; j < pageContextNames.length; j++ ) {
				isSelected |= userContextName.getName().equalsIgnoreCase(pageContextNames[j]);
			}
		}

		return isSelected;
	}

}
